import { v4 as uuidv4 } from 'uuid'
import OpenAI from 'openai'
import dotenv from 'dotenv'
import fetch from 'node-fetch'

dotenv.config()

// ChromaDB API 配置
const CHROMA_API_URL = process.env.CHROMA_API_URL || 'http://localhost:8001'
const COLLECTION_NAME = 'wind_blade_defects'
const RECONNECT_INTERVAL = 5000 // 5秒

class ChatMemoryManager {
  constructor() {
    this.embeddingClient = null
    this.initialized = false
    this.useChromaDB = false
    this.inMemoryStore = []
    this.mode = 'unknown' // 'api' | 'memory'
    this.reconnectInterval = null
    this.reconnectAttempts = 0
    this.maxReconnectAttempts = -1 // -1 表示无限重试
    this.isConnected = false
    this.lastError = null
  }

  async initialize() {
    if (this.initialized) return

    console.log('🔄 正在初始化 ChatMemoryManager...')

    // 初始化嵌入模型客户端
    this.initializeEmbeddingClient()

    // 测试 ChromaDB API 连接
    await this.testChromaDBConnection()

    // 启动自动重连机制
    this.startAutoReconnect()

    this.initialized = true
    console.log(`✅ ChatMemoryManager 初始化完成，模式: ${this.mode}`)
  }

  initializeEmbeddingClient() {
    if (process.env.ALIYUN_API_KEY && process.env.ALIYUN_BASE_URL) {
      this.embeddingClient = new OpenAI({
        apiKey: process.env.ALIYUN_API_KEY,
        baseURL: process.env.ALIYUN_BASE_URL
      })
      console.log('✅ 已配置阿里云嵌入模型客户端')
    } else if (process.env.OPENAI_KEY) {
      this.embeddingClient = new OpenAI({
        apiKey: process.env.OPENAI_KEY
      })
      console.log('✅ 已配置 OpenAI 嵌入模型客户端')
    } else {
      console.warn('⚠️ 未配置嵌入模型，将使用简单嵌入方法')
    }
  }

  async testChromaDBConnection() {
    try {
      console.log(`🔄 [ChromaDB] 尝试连接到 ${CHROMA_API_URL}...`)
      
      // 直接调用 Flask API 的健康检查
      const response = await fetch(`${CHROMA_API_URL}/api/health`, {
        signal: AbortSignal.timeout(5000)
      })
      
      if (response.ok) {
        const data = await response.json()
        this.isConnected = true
        this.reconnectAttempts = 0
        this.lastError = null
        
        console.log(`✅ [ChromaDB] 连接成功！当前有 ${data.count} 条记录`)
        
        // 停止重连定时器
        if (this.reconnectInterval) {
          clearInterval(this.reconnectInterval)
          this.reconnectInterval = null
        }
        
        this.useChromaDB = true
        this.mode = 'api'
      } else {
        throw new Error(`HTTP ${response.status}`)
      }
    } catch (error) {
      this.isConnected = false
      this.lastError = error.message
      console.error(`❌ [ChromaDB] 连接失败:`, error.message)
      
      // 启动自动重连
      this.startAutoReconnect()
      
      this.useChromaDB = false
      this.mode = 'memory'
    }
  }

  // 启动自动重连机制
  startAutoReconnect() {
    if (this.reconnectInterval) {
      return // 已经在运行
    }

    console.log(`🔁 [ChromaDB] 启动自动重连机制 (每 ${RECONNECT_INTERVAL / 1000} 秒尝试一次)...`)
    
    this.reconnectInterval = setInterval(async () => {
      if (this.isConnected) {
        clearInterval(this.reconnectInterval)
        this.reconnectInterval = null
        return
      }
      
      this.reconnectAttempts++
      console.log(`🔄 [ChromaDB] 重连尝试 #${this.reconnectAttempts}...`)
      
      await this.testChromaDBConnection()
    }, RECONNECT_INTERVAL)
  }

  // 停止自动重连
  stopAutoReconnect() {
    if (this.reconnectInterval) {
      clearInterval(this.reconnectInterval)
      this.reconnectInterval = null
      console.log('⏹️ 已停止自动重连机制')
    }
  }

  // 计算余弦相似度
  cosineSimilarity(a, b) {
    if (!a || !b || a.length !== b.length) return 0
    let dot = 0, magA = 0, magB = 0
    for (let i = 0; i < a.length; i++) {
      dot += a[i] * b[i]
      magA += a[i] * a[i]
      magB += b[i] * b[i]
    }
    if (magA === 0 || magB === 0) return 0
    return dot / (Math.sqrt(magA) * Math.sqrt(magB))
  }

  // 生成文本嵌入向量
  async generateEmbedding(text) {
    if (this.embeddingClient) {
      try {
        const model = process.env.EMBEDDING_MODEL || 'text-embedding-v2'
        const response = await this.embeddingClient.embeddings.create({
          model: model,
          input: text.substring(0, 2000)
        })
        const embedding = response.data[0].embedding
        console.log(`✅ 向量生成成功，模型: ${model}, 维度: ${embedding.length}`)
        return embedding
      } catch (err) {
        console.error(`❌ 调用嵌入模型失败: ${err.message}`)
        if (err.message.includes('model') || err.message.includes('not found')) {
          console.warn('💡 提示：阿里云支持的嵌入模型名称：text-embedding-v2, text-embedding-v3')
        }
        console.warn('⚠️ 回退到简单嵌入方法')
        return this.simpleEmbedding(text)
      }
    }
    console.warn('⚠️ 未配置嵌入模型客户端，使用简单嵌入方法')
    return this.simpleEmbedding(text)
  }

  // 简单的备用嵌入方法
  simpleEmbedding(text) {
    const dim = 384
    const vector = new Array(dim).fill(0)
    for (let i = 0; i < text.length && i < dim; i++) {
      const charCode = text.charCodeAt(i)
      vector[i % dim] += charCode / 1000
      vector[(i + 100) % dim] += (i / text.length)
    }
    const magnitude = Math.sqrt(vector.reduce((sum, val) => sum + val * val, 0))
    return vector.map(val => magnitude > 0 ? val / magnitude : 0)
  }

  // 保存对话
  async saveConversation(userMessage, botResponse, metadata = {}) {
    if (!this.initialized) {
      await this.initialize()
    }

    const conversationId = uuidv4()
    const timestamp = new Date().toISOString()
    const conversationText = `用户: ${userMessage}\n助手: ${botResponse}`
    
    console.log(`💾 正在保存对话: ${conversationId.substring(0, 8)}...`)
    
    const embedding = await this.generateEmbedding(conversationText)

    const conversationMetadata = {
      conversationId,
      userMessage,
      botResponse,
      timestamp,
      ...metadata
    }

    // 使用 ChromaDB API
    if (this.useChromaDB) {
      try {
        const response = await fetch(`${CHROMA_API_URL}/api/save`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            id: conversationId,
            embedding: embedding,
            metadata: conversationMetadata,
            document: conversationText
          }),
          signal: AbortSignal.timeout(10000) // 10秒超时
        })
        
        if (response.ok) {
          const result = await response.json()
          console.log(`✅ 对话已保存到 ChromaDB (${this.mode} 模式)`)
          return conversationId
        } else {
          throw new Error(`HTTP ${response.status}: ${await response.text()}`)
        }
      } catch (err) {
        console.error('❌ 保存到 ChromaDB 失败:', err.message)
        console.warn('⚠️ ChromaDB 连接断开，切换到内存模式')
        this.useChromaDB = false
        this.mode = 'memory'
      }
    }

    // 回退到内存存储
    this.inMemoryStore.push({ 
      id: conversationId, 
      embedding, 
      metadata: conversationMetadata, 
      document: conversationText 
    })
    console.log(`💾 对话已保存到进程内存 (共 ${this.inMemoryStore.length} 条)`)
    return conversationId
  }

  // 语义搜索
  async searchRelevantConversations(query, limit = 5) {
    if (!this.initialized) {
      await this.initialize()
    }

    console.log(`🔍 正在搜索相关对话，查询: "${query.substring(0, 50)}..."`)

    const queryEmbedding = await this.generateEmbedding(query)

    if (this.useChromaDB) {
      try {
        const response = await fetch(`${CHROMA_API_URL}/api/search`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            embedding: queryEmbedding,
            limit: limit
          })
        })
        
        if (response.ok) {
          const result = await response.json()
          const conversations = result.conversations.map(conv => ({
            id: conv.id,
            distance: conv.distance,
            similarity: conv.distance !== null ? (1 - conv.distance) : null,
            metadata: conv.metadata,
            document: conv.document
          }))
          
          console.log(`✅ 从 ChromaDB 找到 ${conversations.length} 条相关对话`)
          if (conversations.length > 0 && conversations[0].similarity !== null) {
            console.log(`   最相关的相似度: ${(conversations[0].similarity * 100).toFixed(1)}%`)
          }
          return conversations
        } else {
          throw new Error(`HTTP ${response.status}`)
        }
      } catch (err) {
        console.error('❌ ChromaDB 搜索失败:', err.message)
        this.useChromaDB = false
        this.mode = 'memory'
      }
    }

    // 内存检索
    const scored = this.inMemoryStore.map(item => {
      const score = this.cosineSimilarity(queryEmbedding, item.embedding)
      return { 
        id: item.id, 
        score, 
        similarity: score,
        distance: 1 - score,
        metadata: item.metadata, 
        document: item.document 
      }
    })
    scored.sort((a, b) => b.score - a.score)
    
    const results = scored.slice(0, limit)
    console.log(`✅ 从进程内存找到 ${results.length} 条相关对话`)
    if (results.length > 0) {
      console.log(`   最相关的相似度: ${(results[0].similarity * 100).toFixed(1)}%`)
    }
    return results
  }

  // 获取最近对话（支持分页和日期筛选）
  async getRecentConversations(limit = 20, page = 1, dateFilter = 'all') {
    if (!this.initialized) {
      await this.initialize()
    }

    console.log(`📜 [ChatMemoryManager] 正在获取历史记录 - 页码: ${page}, 每页: ${limit}, 筛选: ${dateFilter}`)

    if (this.useChromaDB) {
      try {
        const params = new URLSearchParams({ 
          limit: limit.toString(), 
          page: page.toString(),
          dateFilter 
        })
        const url = `${CHROMA_API_URL}/api/recent?${params}`
        console.log(`🔗 [ChatMemoryManager] 请求 ChromaDB: ${url}`)
        
        const response = await fetch(url)
        
        if (response.ok) {
          const result = await response.json()
          console.log(`✅ [ChatMemoryManager] ChromaDB 原始返回:`, JSON.stringify(result, null, 2))
          console.log(`📊 [ChatMemoryManager] 解析结果:`, {
            conversations_count: result.conversations?.length || 0,
            total: result.total,
            hasMore: result.hasMore,
            page: result.page
          })
          
          // 确保返回完整的数据结构
          return {
            conversations: result.conversations || [],
            total: result.total !== undefined ? result.total : (result.conversations?.length || 0),
            hasMore: result.hasMore !== undefined ? result.hasMore : false,
            page: result.page !== undefined ? result.page : page
          }
        } else {
          const errorText = await response.text()
          console.error(`❌ [ChatMemoryManager] ChromaDB 返回错误: HTTP ${response.status}`, errorText)
          throw new Error(`HTTP ${response.status}: ${errorText}`)
        }
      } catch (err) {
        console.error('❌ [ChatMemoryManager] 获取 ChromaDB 历史失败:', err.message)
        console.warn('⚠️ [ChatMemoryManager] 回退到内存模式')
        this.useChromaDB = false
        this.mode = 'memory'
      }
    }

    // 内存返回（支持日期筛选）
    console.log(`📦 [ChatMemoryManager] 使用内存模式，当前存储: ${this.inMemoryStore.length} 条`)
    let filtered = [...this.inMemoryStore]
    
    // 日期筛选
    if (dateFilter !== 'all') {
      const now = new Date()
      filtered = filtered.filter(item => {
        const timestamp = item.metadata?.timestamp
        if (!timestamp) return false
        
        const itemDate = new Date(timestamp)
        
        switch (dateFilter) {
          case 'today':
            return itemDate.toDateString() === now.toDateString()
          case 'yesterday':
            const yesterday = new Date(now)
            yesterday.setDate(yesterday.getDate() - 1)
            return itemDate.toDateString() === yesterday.toDateString()
          case 'week':
            const weekAgo = new Date(now)
            weekAgo.setDate(weekAgo.getDate() - 7)
            return itemDate >= weekAgo
          case 'month':
            const monthAgo = new Date(now)
            monthAgo.setDate(monthAgo.getDate() - 30)
            return itemDate >= monthAgo
          case 'year':
            return itemDate.getFullYear() === now.getFullYear()
          default:
            return true
        }
      })
    }
    
    // 排序
    filtered.sort((a, b) => 
      (b.metadata?.timestamp || '').localeCompare(a.metadata?.timestamp || '')
    )
    
    // 分页
    const total = filtered.length
    const start = (page - 1) * limit
    const end = start + limit
    const pageData = filtered.slice(start, end)
    const hasMore = end < total
    
    console.log(`✅ [ChatMemoryManager] 从进程内存返回 ${pageData.length} 条历史记录（总共 ${total} 条）`)
    return {
      conversations: pageData.map(item => ({ 
        id: item.id, 
        metadata: item.metadata, 
        document: item.document 
      })),
      total,
      hasMore,
      page
    }
  }

  // 删除对话
  async deleteConversation(conversationId) {
    if (!this.initialized) {
      await this.initialize()
    }

    if (this.useChromaDB) {
      try {
        const response = await fetch(`${CHROMA_API_URL}/api/delete/${conversationId}`, {
          method: 'DELETE'
        })
        if (response.ok) {
          console.log('🗑️ 对话已删除 (ChromaDB):', conversationId)
          return true
        }
      } catch (err) {
        console.error('删除 ChromaDB 对话失败:', err.message)
      }
    }

    // 内存删除
    const before = this.inMemoryStore.length
    this.inMemoryStore = this.inMemoryStore.filter(i => i.id !== conversationId)
    const ok = this.inMemoryStore.length < before
    if (ok) console.log('🗑️ 对话已删除 (内存):', conversationId)
    return ok
  }

  // 清空所有对话
  async clearAllConversations() {
    if (!this.initialized) {
      await this.initialize()
    }

    if (this.useChromaDB) {
      try {
        const response = await fetch(`${CHROMA_API_URL}/api/clear`, {
          method: 'POST'
        })
        if (response.ok) {
          console.log('🗑️ ChromaDB 历史已清空')
          return true
        }
      } catch (err) {
        console.error('清空 ChromaDB 历史失败:', err.message)
      }
    }

    // 清空内存
    this.inMemoryStore = []
    console.log('🗑️ 进程内存历史已清空')
    return true
  }

  // 获取统计信息
  async getStats() {
    if (!this.initialized) {
      await this.initialize()
    }

    const stats = {
      mode: this.mode,
      initialized: this.initialized,
      useChromaDB: this.useChromaDB,
      hasEmbeddingClient: !!this.embeddingClient,
      totalConversations: 0,
      reconnectAttempts: this.reconnectAttempts,
      autoReconnectEnabled: !!this.reconnectInterval
    }

    if (this.useChromaDB) {
      try {
        const response = await fetch(`${CHROMA_API_URL}/api/health`, {
          signal: AbortSignal.timeout(5000)
        })
        if (response.ok) {
          const data = await response.json()
          stats.totalConversations = data.count
          stats.chromaDBStatus = 'connected'
        }
      } catch (err) {
        console.error('获取统计信息失败:', err.message)
        stats.chromaDBStatus = 'error'
      }
    } else {
      stats.totalConversations = this.inMemoryStore.length
      stats.chromaDBStatus = 'disconnected'
    }

    return stats
  }

  // 构建带上下文的 prompt
  async buildContextualPrompt(currentMessage, includeHistory = true) {
    if (!includeHistory) return currentMessage

    try {
      const relevantConversations = await this.searchRelevantConversations(currentMessage, 3)
      
      if (relevantConversations.length === 0) {
        return currentMessage
      }

      let context = '以下是相关的历史对话记录：\n\n'
      relevantConversations.forEach((conv, index) => {
        const meta = conv.metadata
        context += `[历史对话 ${index + 1}]\n`
        context += `用户: ${meta.userMessage}\n`
        context += `助手: ${meta.botResponse}\n\n`
      })

      context += `当前问题: ${currentMessage}`
      
      return context
    } catch (err) {
      console.error('构建上下文 prompt 失败:', err.message)
      return currentMessage
    }
  }
}

const chatMemoryManager = new ChatMemoryManager()
export default chatMemoryManager
